//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using OpenLS.Spreadsheet.Expressions;
using OpenLS.Spreadsheet.Formats.Biff.Records;
using OpenLS.Spreadsheet.Internals;

namespace OpenLS.Spreadsheet.Formats.Biff
{
    internal class BiffReaderWorksheetContext: IDisposable
    {
        private readonly Dictionary<int, ObjRecord> _objRecords = new Dictionary<int, ObjRecord>();
        public Window2Record LastWindow2Record{ get; set; }
        public double DefaultRowHeight { get; set; }
        private readonly BiffReaderWorkbookContext _parentContext;
        readonly SharedFormulaDictionary<SharedExpression> _sharedFormulas = new SharedFormulaDictionary<SharedExpression>();

        private readonly Worksheet _worksheet;
        private readonly Dictionary<CellAddress, ArrayFormula> _arrayFormulas = new Dictionary<CellAddress, ArrayFormula>();

        public CondFmtRecordBase CurrentCondFmtRecord { get { return _condFmtRecords[_condFmtRecords.Count - 1]; } }

        readonly List<CondFmtRecordBase> _condFmtRecords = new List<CondFmtRecordBase>();
        public void AddCondFmtRecord (CondFmtRecordBase record)
        {
            this._condFmtRecords.Add(record);
        }

        public BiffReaderWorksheetContext(BiffReaderWorkbookContext parentContext, Worksheet worksheet)
        {
            Contract.Requires(worksheet != null);
            Contract.Requires(parentContext != null);
            _parentContext = parentContext;
            _worksheet = worksheet;

            _rowGroupStack = new GroupBuilderStack<Row>(worksheet.RootRowGroup,
                                  (parent, first, last) =>
                                  RowGroup.CreateColumnGroupWithLast
                                      (parent, (Row)first,
                                       (Row)last));
            ColumnGroupStack = new GroupBuilderStack<Column>(worksheet.RootColumnGroup,
                                  (parent, first, last) =>
                                  ColumnGroup.CreateColumnGroupWithLast
                                      (parent, (Column)first,
                                       (Column)last));
        }

        readonly GroupBuilderStack<Row> _rowGroupStack;
        private GroupBuilderStack<Column> _columnGroupStack;

        internal GroupBuilderStack<Row> RowGroupStack
         {
             get
             {
                 Contract.Ensures(Contract.Result<GroupBuilderStack<Row>>() != null);
                 return _rowGroupStack;
             }
         }

        internal BiffRecord PreviousRecord { get; set; }

        public BiffReaderWorkbookContext WorkbookContext
        {
            get { return _parentContext; }
        }

        public Worksheet Worksheet
        {
            get { return _worksheet; }
        }

        public SharedFormulaDictionary<SharedExpression> SharedFormulas
        {
            get { return _sharedFormulas; }
        }
        public Dictionary<CellAddress, ArrayFormula> ArrayFormulas
        {
            get { return _arrayFormulas; }
        }

        public GroupBuilderStack<Column> ColumnGroupStack
        {
            get { return _columnGroupStack; }
            set { _columnGroupStack = value; }
        }

        public BiffReaderWorkbookContext ParentContext
        {
            get {
                return _parentContext;
            }
        }

        public Dictionary<int, ObjRecord> ObjRecords
        {
            get { return _objRecords; }
        }



        public void Dispose()
        {
            this.RowGroupStack.Close();
            this.ColumnGroupStack.Close();
        }

        public CondFmtRecord GetCondFmtRecord(ushort nId)
        {
            return Enumerable.FirstOrDefault(Enumerable.OfType<CondFmtRecord>(this._condFmtRecords), c => c.Id == nId);
        }
    }
}